关于使用Axis2 webservice 处理Fault响应时抛org.apache.axis2.AxisFault的分析

您所在的位置:网站首页 webservice fault occurred 关于使用Axis2 webservice 处理Fault响应时抛org.apache.axis2.AxisFault的分析

关于使用Axis2 webservice 处理Fault响应时抛org.apache.axis2.AxisFault的分析

2023-06-07 12:37| 来源: 网络整理| 查看: 265

使用Axis2这个框架进行webservice协议通讯,期间出了个问题,我(CLIENT)请求后,当服务端返回符合协议的SOAP异常报文,例如 ...

我的程序直接抛org.apache.axis2.AxisFault异常,导致连服务端给我们的报文都没有接收成功。 

--请注意,是我连报文都没有接收成功,而不是接收成功后我解析失败了。

 

 

[java] view plain copy print? try {            ServiceClient serviceClient = new ServiceClient();            Options options = new Options();            //设置超时时间,单位毫秒            options.setTimeOutInMilliSeconds(this.wsTimeOut);              options.setTransportInProtocol(Constants.TRANSPORT_HTTP);              options.setTo(new EndpointReference(this.wsEndpointAddress));              options.setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI);              options.setAction(this.wsMethod);              MessageContext requetMessageContext = new MessageContext();              SOAPEnvelope env = this.getRequestEnvelope();              log.info("version : "+ env.getVersion().getEnvelopeURI());               requetMessageContext.setEnvelope(env);                              OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP);               opClient.addMessageContext(requetMessageContext);               opClient.setOptions(options);               opClient.execute(true);               MessageContext rspMC = opClient.getMessageContext("In");               response = rspMC.getEnvelope().getBody().getFirstElement();            log.info("应答报文: "+ rspMC.getEnvelope());         } catch (AxisFault e) {            this.errRspDesc = "xxxxx";            log.error("soapDispatch AxisFault!");            throw e;         } catch (Exception e) {            this.errRspDesc = "xxxxxxxxxxxxx!";            log.error("soapDispatch Exception!");            throw e;         }   try { ServiceClient serviceClient = new ServiceClient(); Options options = new Options(); //设置超时时间,单位毫秒 options.setTimeOutInMilliSeconds(this.wsTimeOut); options.setTransportInProtocol(Constants.TRANSPORT_HTTP); options.setTo(new EndpointReference(this.wsEndpointAddress)); options.setSoapVersionURI(org.apache.axiom.soap.SOAP12Constants.SOAP_ENVELOPE_NAMESPACE_URI); options.setAction(this.wsMethod); MessageContext requetMessageContext = new MessageContext(); SOAPEnvelope env = this.getRequestEnvelope(); log.info("version : "+ env.getVersion().getEnvelopeURI()); requetMessageContext.setEnvelope(env); OperationClient opClient = serviceClient.createClient(ServiceClient.ANON_OUT_IN_OP); opClient.addMessageContext(requetMessageContext); opClient.setOptions(options); opClient.execute(true); MessageContext rspMC = opClient.getMessageContext("In"); response = rspMC.getEnvelope().getBody().getFirstElement(); log.info("应答报文: "+ rspMC.getEnvelope()); } catch (AxisFault e) { this.errRspDesc = "xxxxx"; log.error("soapDispatch AxisFault!"); throw e; } catch (Exception e) { this.errRspDesc = "xxxxxxxxxxxxx!"; log.error("soapDispatch Exception!"); throw e; }

 

当执行到发送请求opClient.execute(true); 

服务端成功返回格式正常的SOAP异常报文,此时程序直接抛异常,走不到下面rspMC的获取,也就拿不到响应报文。

 

经过一段时间的查看Axis2源码,终于找到原因。

从opClient.execute(true); 入手,可以看到

 

[java] view plain copy print? public final void execute(boolean block) throws AxisFault {          this.sc.setLastOperationContext(this.oc);          this.executeImpl(block);      }   public final void execute(boolean block) throws AxisFault { this.sc.setLastOperationContext(this.oc); this.executeImpl(block); }

 

再看this.executeImpl(block);

 

[java] view plain copy print? public void executeImpl(boolean block) throws AxisFault {          if(log.isDebugEnabled()) {              log.debug("Entry: OutInAxisOperationClient::execute, " + block);          }             if(this.completed) {              throw new AxisFault(Messages.getMessage("mepiscomplted"));          } else {              ConfigurationContext cc = this.sc.getConfigurationContext();              MessageContext mc = this.oc.getMessageContext("Out");              if(mc == null) {                  throw new AxisFault(Messages.getMessage("outmsgctxnull"));              } else {                  this.prepareMessageContext(cc, mc);                  if(this.options.getTransportIn() == null && mc.getTransportIn() == null) {                      mc.setTransportIn(ClientUtils.inferInTransport(cc.getAxisConfiguration(), this.options, mc));                  } else if(mc.getTransportIn() == null) {                      mc.setTransportIn(this.options.getTransportIn());                  }                     boolean useAsync = false;                  if(!mc.getOptions().isUseSeparateListener()) {                      Boolean replyTo = (Boolean)mc.getProperty("UseAsyncOperations");                      if(log.isDebugEnabled()) {                          log.debug("OutInAxisOperationClient: useAsyncOption " + replyTo);                      }                         if(replyTo != null) {                          useAsync = replyTo.booleanValue();                      }                  }                     EndpointReference replyTo1 = mc.getReplyTo();                  if(replyTo1 != null) {                      if(replyTo1.hasNoneAddress()) {                          throw new AxisFault(replyTo1.getAddress() + "" + " can not be used with OutInAxisOperationClient , user either " + "fireAndForget or sendRobust)");                      }                         if(replyTo1.isWSAddressingAnonymous() && replyTo1.getAllReferenceParameters() != null) {                          mc.setProperty("includeOptionalHeaders", Boolean.TRUE);                      }                         String customReplyTo = (String)this.options.getProperty(Options.CUSTOM_REPLYTO_ADDRESS);                      if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) {                          useAsync = true;                      }                  }                     if(!useAsync && !mc.getOptions().isUseSeparateListener()) {                      if(block) {                          this.send(mc);                          this.completed = true;                      } else {                          this.sc.getConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback));                      }                  } else {                      this.sendAsync(useAsync, mc);                  }                 }          }      }   public void executeImpl(boolean block) throws AxisFault { if(log.isDebugEnabled()) { log.debug("Entry: OutInAxisOperationClient::execute, " + block); } if(this.completed) { throw new AxisFault(Messages.getMessage("mepiscomplted")); } else { ConfigurationContext cc = this.sc.getConfigurationContext(); MessageContext mc = this.oc.getMessageContext("Out"); if(mc == null) { throw new AxisFault(Messages.getMessage("outmsgctxnull")); } else { this.prepareMessageContext(cc, mc); if(this.options.getTransportIn() == null && mc.getTransportIn() == null) { mc.setTransportIn(ClientUtils.inferInTransport(cc.getAxisConfiguration(), this.options, mc)); } else if(mc.getTransportIn() == null) { mc.setTransportIn(this.options.getTransportIn()); } boolean useAsync = false; if(!mc.getOptions().isUseSeparateListener()) { Boolean replyTo = (Boolean)mc.getProperty("UseAsyncOperations"); if(log.isDebugEnabled()) { log.debug("OutInAxisOperationClient: useAsyncOption " + replyTo); } if(replyTo != null) { useAsync = replyTo.booleanValue(); } } EndpointReference replyTo1 = mc.getReplyTo(); if(replyTo1 != null) { if(replyTo1.hasNoneAddress()) { throw new AxisFault(replyTo1.getAddress() + "" + " can not be used with OutInAxisOperationClient , user either " + "fireAndForget or sendRobust)"); } if(replyTo1.isWSAddressingAnonymous() && replyTo1.getAllReferenceParameters() != null) { mc.setProperty("includeOptionalHeaders", Boolean.TRUE); } String customReplyTo = (String)this.options.getProperty(Options.CUSTOM_REPLYTO_ADDRESS); if(!Options.CUSTOM_REPLYTO_ADDRESS_TRUE.equals(customReplyTo) && !replyTo1.hasAnonymousAddress()) { useAsync = true; } } if(!useAsync && !mc.getOptions().isUseSeparateListener()) { if(block) { this.send(mc); this.completed = true; } else { this.sc.getConfigurationContext().getThreadPool().execute(new OutInAxisOperationClient.NonBlockingInvocationWorker(this.callback, mc, this.axisCallback)); } } else { this.sendAsync(useAsync, mc); } } } }

 

进send(mc)方法

 

 

 

 

[java] view plain copy print? protected MessageContext send(MessageContext msgContext) throws AxisFault {          MessageContext responseMessageContext = msgContext.getConfigurationContext().createMessageContext();          responseMessageContext.setServerSide(false);          responseMessageContext.setOperationContext(msgContext.getOperationContext());          responseMessageContext.setOptions(new Options(this.options));          responseMessageContext.setMessageID(msgContext.getMessageID());          this.addMessageContext(responseMessageContext);          responseMessageContext.setServiceContext(msgContext.getServiceContext());          responseMessageContext.setAxisMessage(this.axisOp.getMessage("In"));          AxisEngine.send(msgContext);          responseMessageContext.setDoingREST(msgContext.isDoingREST());          responseMessageContext.setProperty("TRANSPORT_HEADERS", msgContext.getProperty("TRANSPORT_HEADERS"));          responseMessageContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE));          responseMessageContext.setProperty("TRANSPORT_IN", msgContext.getProperty("TRANSPORT_IN"));          responseMessageContext.setTransportIn(msgContext.getTransportIn());          responseMessageContext.setTransportOut(msgContext.getTransportOut());          this.handleResponse(responseMessageContext);          return responseMessageContext;      }   protected MessageContext send(MessageContext msgContext) throws AxisFault { MessageContext responseMessageContext = msgContext.getConfigurationContext().createMessageContext(); responseMessageContext.setServerSide(false); responseMessageContext.setOperationContext(msgContext.getOperationContext()); responseMessageContext.setOptions(new Options(this.options)); responseMessageContext.setMessageID(msgContext.getMessageID()); this.addMessageContext(responseMessageContext); responseMessageContext.setServiceContext(msgContext.getServiceContext()); responseMessageContext.setAxisMessage(this.axisOp.getMessage("In")); AxisEngine.send(msgContext); responseMessageContext.setDoingREST(msgContext.isDoingREST()); responseMessageContext.setProperty("TRANSPORT_HEADERS", msgContext.getProperty("TRANSPORT_HEADERS")); responseMessageContext.setProperty(HTTPConstants.MC_HTTP_STATUS_CODE, msgContext.getProperty(HTTPConstants.MC_HTTP_STATUS_CODE)); responseMessageContext.setProperty("TRANSPORT_IN", msgContext.getProperty("TRANSPORT_IN")); responseMessageContext.setTransportIn(msgContext.getTransportIn()); responseMessageContext.setTransportOut(msgContext.getTransportOut()); this.handleResponse(responseMessageContext); return responseMessageContext; }

 

 

这里就是发送请求并接收响应的地方 再看倒数第二行this.handleResponse(responseMessageContext);

 

 

 

[java] view plain copy print? protected void handleResponse(MessageContext responseMessageContext) throws AxisFault {        responseMessageContext.setSoapAction((String)null);        SOAPEnvelope resenvelope;        if(responseMessageContext.getEnvelope() == null) {            resenvelope = TransportUtils.createSOAPMessage(responseMessageContext);            if(resenvelope == null) {                throw new AxisFault(Messages.getMessage("blockingInvocationExpectsResponse"));            }               responseMessageContext.setEnvelope(resenvelope);        }           resenvelope = responseMessageContext.getEnvelope();        if(resenvelope != null) {            AxisEngine.receive(responseMessageContext);            if(responseMessageContext.getReplyTo() != null) {                this.sc.setTargetEPR(responseMessageContext.getReplyTo());            }               resenvelope = responseMessageContext.getEnvelope();            if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) {                throw Utils.getInboundFaultFromMessageContext(responseMessageContext);            }        }       }   protected void handleResponse(MessageContext responseMessageContext) throws AxisFault { responseMessageContext.setSoapAction((String)null); SOAPEnvelope resenvelope; if(responseMessageContext.getEnvelope() == null) { resenvelope = TransportUtils.createSOAPMessage(responseMessageContext); if(resenvelope == null) { throw new AxisFault(Messages.getMessage("blockingInvocationExpectsResponse")); } responseMessageContext.setEnvelope(resenvelope); } resenvelope = responseMessageContext.getEnvelope(); if(resenvelope != null) { AxisEngine.receive(responseMessageContext); if(responseMessageContext.getReplyTo() != null) { this.sc.setTargetEPR(responseMessageContext.getReplyTo()); } resenvelope = responseMessageContext.getEnvelope(); if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) { throw Utils.getInboundFaultFromMessageContext(responseMessageContext); } } }

 

 

这时,我们可以看到一个很有趣的方法, if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) 总算是跟我们的异常报文有关了。跟进去看一下

 

 

[java] view plain copy print? public boolean hasFault() {         QName payloadQName = this.getPayloadQName_Optimized();         if(payloadQName != null && "Fault".equals(payloadQName.getLocalPart())) {             String body1 = payloadQName.getNamespaceURI();             return "http://schemas.xmlsoap.org/soap/envelope/".equals(body1) || "http://www.w3.org/2003/05/soap-envelope".equals(body1);         } else {             SOAPBody body = this.getBody();             return body == null?false:body.hasFault();         }     }   public boolean hasFault() { QName payloadQName = this.getPayloadQName_Optimized(); if(payloadQName != null && "Fault".equals(payloadQName.getLocalPart())) { String body1 = payloadQName.getNamespaceURI(); return "http://schemas.xmlsoap.org/soap/envelope/".equals(body1) || "http://www.w3.org/2003/05/soap-envelope".equals(body1); } else { SOAPBody body = this.getBody(); return body == null?false:body.hasFault(); } }

 

可以看到Axis2的内部处理机制,就是一但发现响应报文有Fault节点,它就要抛异常。总算找到源头了 那要如何解决这个问题 我们可以看到 if((resenvelope.hasFault() || responseMessageContext.isProcessingFault()) && this.options.isExceptionToBeThrownOnSOAPFault()) {                 throw Utils.getInboundFaultFromMessageContext(responseMessageContext);             } 这里还有一个判断条件, this.options.isExceptionToBeThrownOnSOAPFault() 当它为TRUE时才抛异常。 这就是options的一个参数,可配置,所以给我们的代码加上

 

[java] view plain copy print? options.setExceptionToBeThrownOnSOAPFault(false);   options.setExceptionToBeThrownOnSOAPFault(false);

 

 

就不抛异常了,能够正常获取并解析响应报文。 总结:一切的害怕源于对代码的神秘,未知,当你把它当成自己写的代码,去反编译,去阅读,那就不会再害怕!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3